﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Text.RegularExpressions;

namespace Bamboo.Utils
{
    /// <summary>
    /// 滚动删除
    /// </summary>
    public class FileRoller
    {
        public List<FileRollerItem> InputFiles { get; } = new List<FileRollerItem>();
        /// <summary>
        /// 保留最新的文件个数
        /// </summary>
        public int RemainCount1;
        /// <summary>
        /// 保留最新的天数，每天一个文件
        /// </summary>
        public int RemainCount2;
        /// <summary>
        /// 保留最新的月份数，每月一个文件
        /// </summary>
        public int RemainCount3;

        public List<FileRollerItem> RemainFiles1 = new List<FileRollerItem>();
        public Dictionary<int, FileRollerItem> RemainFiles2 = new Dictionary<int, FileRollerItem>(); //key：YYYYMMDD
        public Dictionary<int, FileRollerItem> RemainFiles3 = new Dictionary<int, FileRollerItem>(); //key：YYYYMM

        public void Reset()
        {
            InputFiles.Clear();
            RemainFiles1.Count();
            RemainFiles2.Count();
            RemainFiles3.Count();
        }

        /// <summary>
        /// 从本地目录添加文件
        /// 对于日期的识别，优先从文件名中识别.yyyyMMdd.HHmm，取不到才从文件系统获取它的创建时间
        /// </summary>
        /// <param name="path"></param>
        /// <param name="pattern"></param>
        /// <param name="recursive"></param>
        public void AddFileFromLocalPath(string path, string pattern, bool recursive)
        {
            var regex = new Regex(@"\.(?<year>\d{4})(?<month>\d{2})(?<day>\d{2})\.(?<hour>\d{2})(?<minute>\d{2})");
            var dir = new DirectoryInfo(path);
            var files = dir.GetFiles(pattern, recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);
            foreach (var file in files)
            {
                var item = new FileRollerItem();
                item.FileName = file.FullName;
                var m = regex.Match(file.Name);
                if (m.Success)
                {
                    int year = int.Parse(m.Groups["year"].Value);
                    int month = int.Parse(m.Groups["month"].Value);
                    int day = int.Parse(m.Groups["day"].Value);
                    int hour = int.Parse(m.Groups["hour"].Value);
                    int minute = int.Parse(m.Groups["minute"].Value);
                    item.ModifyTime = new DateTime(year, month, day, hour, minute, 0);
                }
                else
                {
                    item.ModifyTime = file.CreationTime;
                }
                InputFiles.Add(item);
            }
        }

        public void Execute()
        {
            //按日期降序排序
            InputFiles.Sort((a, b) => b.ModifyTime.CompareTo(a.ModifyTime));

            if (InputFiles.Count <= RemainCount1)
            {
                //全部置有效
                foreach (var item in InputFiles) item.Valid = true;
                return;
            }
            else
            {
                //全部置无效
                foreach (var item in InputFiles) item.Valid = false;
            }

            foreach (var file in InputFiles)
            {
                //把最早的30个加到list1
                if (RemainFiles1.Count < RemainCount1)
                {
                    RemainFiles1.Add(file);
                    file.Valid = true;
                }
                else if (RemainFiles2.Count < RemainCount2)
                {
                    int date = file.ModifyTime.Year * 10000 + file.ModifyTime.Month * 100 + file.ModifyTime.Day;
                    if (!RemainFiles2.ContainsKey(date))
                    {
                        RemainFiles2.Add(date, file);
                        file.Valid = true;
                    }
                }
                else if (RemainFiles3.Count < RemainCount3)
                {
                    int yyyymm = file.ModifyTime.Year * 100 + file.ModifyTime.Month;
                    if (!RemainFiles3.ContainsKey(yyyymm))
                    {
                        RemainFiles3.Add(yyyymm, file);
                        file.Valid = true;
                    }
                }
                else
                {
                    break;
                }
            }


        }

        /// <summary>
        /// 获取详细信息
        /// </summary>
        /// <returns></returns>
        public string GetDetailInfo()
        {
            //打印调试信息
            var s = new StringBuilder();
            int removeCount = InputFiles.Count(a => a.Valid == false);
            s.AppendLine($"[FileRoller]合计{InputFiles.Count}个文件, " +
                $"保留最新的{RemainFiles1.Count}个, " +
                $"{RemainFiles2.Count}个每日快照，" +
                $"{RemainFiles3.Count}个每月快照；删除{removeCount}个文件。");
            if (removeCount > 0)
            {
                s.AppendLine($"--------以下是文件操作详情：");
                foreach (var item in InputFiles)
                {
                    if (item.Valid)
                    {
                        s.AppendLine("保留: " + item.FileName);
                    }
                    else
                    {
                        try
                        {
                            File.Delete(item.FileName);
                            s.AppendLine(">>>>删除: " + item.FileName);
                        }
                        catch (Exception ex)
                        {
                            s.AppendLine("[error]删除失败：" + ex.Message);
                        }
                    }
                }
            }
            return s.ToString();
        }
    }

    public class FileRollerItem
    {
        public string FileName;
        /// <summary>
        /// 修改时间，用来决定文件的去留
        /// </summary>
        public DateTime ModifyTime;

        /// <summary>
        /// 是否有效，默认为true
        /// </summary>
        public bool Valid = true;
    }
}
